/* 
 * Copyright (c)	Insighten Intelligent Equipment co.,LTD
 * 
 *  Use of this software is controlled by the terms and conditions found
 *  in the license agreement under which this software has been supplied.
 * 
 */
/** 
 * @file main.c
 * @brief client for wireless project
 * @author taco [tacoee@gmail.com]
 * @version 0.1
 * @date 2010-09-10
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#include "tcp_client.h"
#include "rwbuf.h"
#include "udp_lib.h"
#include "udp_thread.h"

static int quit;

int set_quit()
{
	quit = 1;
}

int get_quit()
{
	return quit;
}

static void helper(char *pro)
{
	fprintf(stderr, "Usage: %s host_address[ip] port[1234] test_message[\"string\"]\n", pro);
}

int main(int argc, char *argv[])
{
	int port;
	char *host_name;
	TcpClient *tcp_cli = NULL;
	UdpSocket *udp_cli = NULL;
	UdpCliEnv *udp_cli_env = NULL;
	SocketAttr attr={0,8192};
	RwBuf	*buf;
	int ret;
	char *msg;
	int maxfd;
	char *lckaddr = inet_ntoa(net_get_ip("eth0"));
	pthread_t udp_thread;
	int udpport = 2345;

	fd_set rset;
	fd_set wset;

	FD_ZERO(&rset);
	FD_ZERO(&wset);


	if (argc < 4) {
		helper(argv[0]);
		exit(1);
	}
	host_name = argv[1];
	port = atol(argv[2]);
	msg = argv[3];

	printf("host name %s\n", argv[1]);
	printf("port %d\n", port);
	printf("message %s\n", msg);

	buf = buf_new((FunMemAlloc)NULL, (FunMemFree)NULL);
	buf_init(buf, 8192);

	memcpy(buf->mem, msg, strlen(msg));
	buf->wpos += strlen(msg);
	udp_cli_env = udp_cli_env_new();
	tcp_cli = tcp_client_new();
	udp_cli = udp_socket_new();

	udp_socket_init(udp_cli, lckaddr, NULL, udpport, &attr);
	tcp_client_init(tcp_cli, port, host_name, &attr, buf);
	tcp_client_create(tcp_cli);
	udp_cli_env_set_lckaddr(udp_cli_env, lckaddr);

#ifdef CONFIG_SCHED_PRIORITY
	pthread_attr_t	pattr;
	struct sched_param sparam;
	sparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
	if (sparam.sched_priority == -1) {
		err_log("Get sched priority.");
		goto cleanup;
	}
	if (pthread_attr_setschedparam(&pattr, &sparam)) {
		err_log("Set sched priority");
		goto cleanup;
	}
	if (pthread_create(&udp_thread, &pattr, udp_cli_thread, (void*)udp_cli_env)) {
		err_log("Create thread error");
		goto cleanup;
	}
#else
	if (pthread_create(&udp_thread, NULL, udp_cli_thread, (void*)udp_cli_env)) {
		err_log("Create thread error");
		goto cleanup;
	}
#endif /*CONFIG_SCHED_PRIORITY*/

	ret = tcp_client_connect(tcp_cli); /*will chang to nonblock connect*/	

	if (ret != RET_OK) {
		err_log("Connect error");
		goto cleanup;
	}

	maxfd = tcp_cli->fd;
	FD_SET(tcp_cli->fd, &wset);

	while(1) {
		ret = select(maxfd+1, &rset, &wset, NULL, NULL);

		if (FD_ISSET(tcp_cli->fd, &wset)) {
			ret = tcp_client_wirte(tcp_cli, strlen(msg));
			tcp_cli->buf->rpos += ret;

			if (ret == strlen(msg)) {
				memset(tcp_cli->buf->mem, 0, tcp_cli->buf->wpos);
				tcp_cli->buf->wpos = 0;
				FD_CLR(tcp_cli->fd, &wset);
				FD_SET(tcp_cli->fd, &rset);
			}
		}
		if (FD_ISSET(tcp_cli->fd, &rset)) {
			ret = tcp_client_read(tcp_cli, 15);
			if (ret >= 0 ) {
				tcp_cli->status = DONE;
				tcp_cli->buf->wpos +=ret;
				FD_CLR(tcp_cli->fd, &rset);
			}
		}
		if (tcp_cli->status == DONE) {
				goto cleanup;
		}
	}
cleanup:
	buf_destroy(buf);
	tcp_client_destroy(tcp_cli);
	return 0;
}
